﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Storage;

class GameSession
{
    private static GameSession singleton;

    private int lastMap = 0;
    private int actualMap = 0;

    public static int screenAdjustment = -54;

    private bool firstTime;

    private bool solved;

    private Vector2 startPosition;

    private List<int> puzzleSolved;
    public List<int> PuzzleSolved
    {
        get { return (singleton == null ? null : singleton.puzzleSolved); }
    }

    string music;

    private EventManager eventManager;
    public static EventManager EventManager
    {
        get { return (singleton == null ? null : singleton.eventManager); }
    }

    private PuzzleManager puzzleManager;
    public static PuzzleManager PuzzleManager
    {
        get { return (singleton == null ? null : singleton.puzzleManager); }
    }

    private ScreenManager screenManager;
    public static ScreenManager ScreenManager
    {
        get { return (singleton == null ? null : singleton.screenManager); }
    }

    private GameplayScreen gameplayScreen;
    public static GameplayScreen GamePlayScreen
    {
        get { return (singleton == null ? null : singleton.gameplayScreen); }
    }

    private HUD hud;
    public static HUD Hud
    {
        get { return (singleton == null ? null : singleton.hud); }
    }

    public static bool IsActive
    {
        get { return singleton != null; }
    }

    private MapControl mapcontroler;
    public static MapControl MapControl
    {
        get { return (singleton == null ? null : singleton.mapcontroler); }
    }

    private int[,] sceneryMatriz = new int[20, 12];
    public static int[,] SceneryMatriz
    {
        get { return (singleton == null ? null : singleton.sceneryMatriz); }
    }

    public int[,] collisionMatriz = new int[20, 12];
    public static int[,] CollisionMatriz
    {
        get { return (singleton == null ? null : singleton.collisionMatriz); }
    }

    public int[,] objectsMatriz = new int[20, 12];
    public static int[,] ObjectsMatriz
    {
        get { return (singleton == null ? null : singleton.objectsMatriz); }
    }

    public int[,] eventsMatriz = new int[3, 40];
    public static int[,] EventsMatriz
    {
        get { return (singleton == null ? null : singleton.eventsMatriz); }
    }

    Texture2D tiles, objects;
    public static Texture2D Tiles
    {
        get { return (singleton == null ? null : singleton.tiles); }
    }

    public static Texture2D Objects
    {
        get { return (singleton == null ? null : singleton.objects); }
    }

    private int tileSize, objectSize;
    public static int TileSize
    {
        get { return (singleton == null ? 0 : singleton.tileSize); }
    }

    public static int ObjectSize
    {
        get { return (singleton == null ? 0 : singleton.objectSize); }
    }

    public static ContentManager Content
    {
        get { return (singleton == null ? null : singleton.screenManager.Game.Content); }
    }

    private static Barrel _barrel;

    public static KeiJow keiJow;
    public static Manteiga manteiga;

    private PlayerAndChar players;
    public static PlayerAndChar Players
    {
        get { return (singleton == null ? PlayerAndChar.NONE : singleton.players); }
    }

    private List<Objects> objectsList;
    public static List<Objects> ObjectsList
    {
        get { return (singleton == null ? null : singleton.objectsList); }
    }

    private List<Barrel> barrelsList;
    public static List<Barrel> BarrelsList
    {
        get { return (singleton == null ? null : singleton.barrelsList); }
    }

    private List<Characters> charactersList;
    public static List<Characters> CharactersList
    {
        get { return (singleton == null ? null : singleton.charactersList); }
    }

    private static CharacterComparer charComparer;
    private static BarrelComparer barrelComparer;

    private string alert = @"Audio/Som de Alerta";
    private string chasing = @"Audio/Musica Perseguindo";

    public static void LoadContent(ContentManager content)
    {
        singleton.tiles = content.Load<Texture2D>(@"Textures/MapMock/tiles");
        singleton.tileSize = singleton.tiles.Width / 64;
        singleton.objects = content.Load<Texture2D>(@"Textures/MapMock/itens");
        singleton.objectSize = singleton.objects.Width / 64;
    }

    private GameSession(ScreenManager screenManager, GameplayScreen gameplayScreen, EventManager eventManager, PuzzleManager puzzleManager)
    {
        // check the parameter
        if (screenManager == null)
        {
            throw new ArgumentNullException("screenManager");
        }
        if (gameplayScreen == null)
        {
            throw new ArgumentNullException("gameplayScreen");
        }
        if (eventManager == null)
        {
            throw new ArgumentNullException("eventManager");
        }
        if (puzzleManager == null)
        {
            throw new ArgumentNullException("puzzleManager");
        }

        // assign the parameter
        this.screenManager = screenManager;
        this.gameplayScreen = gameplayScreen;
        this.eventManager = eventManager;
        this.puzzleManager = puzzleManager;

        // create the HUD interface
        this.hud = new HUD(screenManager);
        this.hud.LoadContent();

        puzzleSolved = new List<int>();

        gameplayScreen.Hud = hud;

        music = @"Audio\Musica Mapas";

        mapcontroler = new MapControl();

        charComparer = new CharacterComparer();
        barrelComparer = new BarrelComparer();
    }

    private double silence = 0;

    private bool firsttime = true;

    private bool allDead;

    private bool reallyDead;

    private double time;

    public static void Update(GameTime gameTime)
    {
        // check the singleton
        if (singleton == null)
        {
            return;
        }

        int count = 0;

        foreach (Objects actualObject in singleton.objectsList)
        {
            if (actualObject.GetType() == typeof(Trap))
            {
                Trap actualPuzzleObject = (Trap)actualObject;
                actualPuzzleObject.Update(gameTime);
            }
            else
                if (actualObject.GetType() == typeof(Tower))
                {
                    Tower actualPuzzleObject = (Tower)actualObject;
                    actualPuzzleObject.Update(gameTime);
                }
                else
                    if (actualObject.GetType() == typeof(PuzzleObject))
                    {

                        PuzzleObject actualPuzzleObject = (PuzzleObject)actualObject;

                        //Console.WriteLine(count + " " + actualPuzzleObject.GetType() + " " + actualPuzzleObject.Kind + " " +
                        //    actualPuzzleObject.CanCollide + " " + actualPuzzleObject.State);

                        actualPuzzleObject.Update(gameTime);
                    }
                    else
                    {
                        actualObject.Update();
                    }

            count++;
        }

        foreach (PuzzleGroup group in singleton.puzzleManager.PuzzleGroups)
            if (group.StoneGroup)
            {
                bool active = true;
                int i = 0;
                foreach (PuzzleObject obj in group.ObjectList)
                {
                    //int i = 0;

                    if (obj.Kind == ObjectKind.StoneButton)
                    {
                        //Console.WriteLine(i + " " + obj.State);
                        i++;
                        if (!IsPressed((int)obj.XPosition, (int)obj.YPosition))
                        {
                            obj.State = false;
                            active = false;
                            break;
                        }
                        else
                            obj.State = true;
                    }
                }

                foreach (PuzzleObject obj in group.ObjectList)
                {
                    if (obj.Kind == ObjectKind.WallUp)
                    {
                        //Console.WriteLine("active "+active);
                        if (active)
                        {
                            obj.State = true;
                        }
                        else
                        {
                            if (obj.State && !singleton.solved)
                                CheckPlayerPosition((int)obj.XPosition, (int)obj.YPosition);

                            obj.State = false;

                        }
                        if (singleton.solved)
                            obj.State = true;
                    }
                }

            }

        bool ischasing = false;

        singleton.allDead = true;

        foreach (Characters character in singleton.charactersList)
        {
            character.Update(gameTime);

            if (character.GetType() != typeof(KeiJow)
                && character.GetType() != typeof(Manteiga))
            {
                Enemies enemy = (Enemies)character;

                if (enemy.State == Characters.States.Alive)
                {

                    if (keiJow != null)
                    {
                        if (enemy.BoundingRectangle.Intersects(keiJow.BoundingRectangle))
                        {
                            keiJow.TakeDamage(1);
                        }
                    }

                    if (manteiga != null)
                    {
                        if (enemy.BoundingRectangle.Intersects(manteiga.BoundingRectangle))
                        {
                            manteiga.TakeDamage(1);
                        }
                    }

                    if (enemy.IsChasing != null && enemy.IsChasing.State == Characters.States.Alive)
                    {
                        if (Vector2.Distance(enemy.Position, enemy.IsChasing.Position) < 300)
                        {
                            enemy.ChasePlayer(enemy.IsChasing);
                            ischasing = true;
                            continue;
                        }
                    }

                    if (keiJow != null)
                    {
                        if (Vector2.Distance(enemy.Position, keiJow.Position) < 300 && keiJow.State == Characters.States.Alive)
                        {
                            enemy.ChasePlayer(keiJow);
                            AudioManager.PlaySound(singleton.alert);
                            ischasing = true;
                            continue;
                        }
                    }

                    if (manteiga != null)
                    {
                        if (Vector2.Distance(enemy.Position, manteiga.Position) < 300 && manteiga.State == Characters.States.Alive)
                        {
                            enemy.ChasePlayer(manteiga);
                            AudioManager.PlaySound(singleton.alert);
                            ischasing = true;
                            continue;
                        }
                    }
                    enemy.IsChasing = null;
                    enemy.RandomWalk(gameTime);

                }

            }
            else
            {
                if (character.State != Characters.States.Dead)
                {
                    singleton.allDead = false;
                }
            }         
        }

        AudioManager.PlayMusic(ischasing ? singleton.chasing : singleton.music);

        foreach (Barrel barrel in BarrelsList)
        {
            if (barrel.Rolled)
            {
                foreach (Characters chara in singleton.charactersList)
                {
                    if (!barrel.Equals(chara._Barrel))
                    {
                        if (chara.BoundingRectangle.Intersects(barrel.BoundingRectangle))
                        {
                            chara.TakeDamage(1);
                        }
                    }
                }
            }
        }

        for (int i = 0; i < singleton.barrelsList.Count; i++)
        {
            singleton.barrelsList[i].Update(gameTime);
        }

        for (int i = 0; i < singleton.objectsList.Count; i++)
        {
            Objects obj = singleton.objectsList[i];
            if (obj.Kind == ObjectKind.Useless)
            {
                singleton.objectsList.Remove(obj);
            }
        }

        if (singleton.allDead && !singleton.reallyDead)
            {
                singleton.time = gameTime.TotalGameTime.TotalMilliseconds;
                singleton.reallyDead = true;
            }

        if (singleton.reallyDead && singleton.time + 1000 <= gameTime.TotalGameTime.TotalMilliseconds)
        {
            ScreenManager.AddScreen(new GameOver());

            Globals.IsPaused = true;
        }

    }

    public static void CheckPlayerPosition(int x, int y)
    {

        foreach (Characters chara in singleton.charactersList)
        {
            if (chara.GetType() == typeof(KeiJow) || chara.GetType() == typeof(Manteiga))
            {
                if ((chara.BoundingRectangle.X / 64) == x
                    && (chara.BoundingRectangle.Y  / 64) == y)
                {
                    chara.TakeDamage(1);
                    chara.Position = singleton.startPosition;
                }
                else
                    if ((chara.BoundingRectangle.X + chara.BoundingRectangle.Width)/ 64 == x
                        && (chara.BoundingRectangle.Y / 64) == y)
                    {
                        chara.TakeDamage(1);
                        chara.Position = singleton.startPosition;
                    }
                    else
                        if ((chara.BoundingRectangle.X / 64) == x
                            && (chara.BoundingRectangle.Y + chara.BoundingRectangle.Height) / 64 == y)
                        {
                            chara.TakeDamage(1);
                            chara.Position = singleton.startPosition;
                        }
                        else
                            if ((chara.BoundingRectangle.X + chara.BoundingRectangle.Width) / 64 == x
                                && (chara.BoundingRectangle.Y + chara.BoundingRectangle.Height)/ 64 == y)
                            {
                                chara.TakeDamage(1);
                                chara.Position = singleton.startPosition;
                            }
            }
        }

    }

    public static bool Collide(int posx, int posy)
    {
        bool returnValue = false;

        int posx64 = posx / 64;
        int posy64 = posy / 64;

        foreach (PuzzleGroup group in singleton.puzzleManager.PuzzleGroups)
            foreach (PuzzleObject obj in group.ObjectList)
            {
                if (obj.XPosition == (int)posx64 && (int)posy64 == obj.YPosition && obj.CanCollide)
                {
                    returnValue = true;
                    break;
                }
            }

        return returnValue;
    }

    private static bool IsPressed(int posx, int posy)
    {
        bool returnValue = false;

        foreach (PuzzleObject obj in GetFirstList())
        {
            if (obj.XPosition == posx && posy == obj.YPosition && obj.Kind == ObjectKind.PushingStone)
            {
                returnValue = true;
                break;
            }
        }

        return returnValue;
    }

    private static IEnumerable<PuzzleObject> GetFirstList()
    {
        foreach (PuzzleGroup group in singleton.puzzleManager.PuzzleGroups)
            if (group.GroupID == -1)
                return group.ObjectList;
        return null;
    }

    public static bool CanCollide(int posx, int posy)
    {
        bool returnValue = false;

        //foreach (PuzzleGroup group in singleton.puzzleManager.PuzzleGroups)
            foreach (Objects obj in singleton.objectsList)
            {
                if (obj.XPosition == posx && posy == obj.YPosition && obj.CanCollide)
                {
                    returnValue = true;
                    break;
                }
            }

        return returnValue;
    }

    public static void Draw(GameTime gameTime)
    {
        //Sort Characters to Draw who is on top first.
        singleton.charactersList.Sort(charComparer);

        singleton.barrelsList.Sort(barrelComparer);

        SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

        spriteBatch.Begin();

        foreach (Characters character in singleton.charactersList)
        {
            character.Draw(gameTime, spriteBatch);
        }

        foreach (Barrel barrel in singleton.barrelsList)
        {
            barrel.Draw(gameTime, spriteBatch);
        }

        spriteBatch.End();
    }

    public static void StartNewSession(ScreenManager screenManager, GameplayScreen gameplayScreen, EventManager eventManager, PuzzleManager puzzleManager)
    {
        Globals.IsPaused = false;

        if (screenManager == null)
        {
            throw new ArgumentNullException("screenManager");
        }
        if (gameplayScreen == null)
        {
            throw new ArgumentNullException("gameplayScreen");
        }

        // end any existing session
        EndSession();

        // create a new singleton
        if (singleton == null) singleton = new GameSession(screenManager, gameplayScreen, eventManager, puzzleManager);

        singleton.charactersList = new List<Characters>();

        singleton.objectsList = new List<Objects>();

        singleton.barrelsList = new List<Barrel>();

        singleton.puzzleManager.PuzzleGroups = new List<PuzzleGroup>();

        singleton.players = Globals.Players;

        singleton.startPosition = new Vector2(200,430);

        switch (singleton.players)
        {
            case PlayerAndChar.CHARA:
                keiJow = new KeiJow(Player.PlayerNumber.ONE, 0.5f, 0.8f, new Vector2(200, 230));
                break;
            case PlayerAndChar.CHARB:
                manteiga = new Manteiga(Player.PlayerNumber.ONE, 0.2f, 0.9f, new Vector2(200, 230));
                break;
            case PlayerAndChar.CHARACHARB:
                keiJow = new KeiJow(Player.PlayerNumber.ONE, 0.5f, 0.8f, new Vector2(200, 230));
                manteiga = new Manteiga(Player.PlayerNumber.TWO, 0.2f, 0.9f, new Vector2(200, 630));
                break;
            case PlayerAndChar.CHARBCHARA:
                manteiga = new Manteiga(Player.PlayerNumber.ONE, 0.2f, 0.9f, new Vector2(200, 230));
                keiJow = new KeiJow(Player.PlayerNumber.TWO, 0.5f, 0.8f, new Vector2(200, 630));
                break;
            case PlayerAndChar.NONE:
                break;
            default:
                break;
        }
        if (keiJow != null)
        {
            keiJow.LoadContent(screenManager.Game.Content);
            singleton.charactersList.Add(keiJow);
        }
        if (manteiga != null)
        {
            manteiga.LoadContent(screenManager.Game.Content);
            singleton.charactersList.Add(manteiga);
        }

        singleton.firstTime = true;

        singleton.reallyDead = false;

        singleton.time = 0;

        AudioManager.PlayMusic(singleton.music);

        singleton.actualMap = 1;

        ChangeMap(1);
    }


    public static void EndSession()
    {
        if (singleton != null)
        {
            GameplayScreen gameplayScreen = singleton.gameplayScreen;
            singleton.gameplayScreen = null;

            AudioManager.StopMusic();

            singleton.charactersList.Clear();
            singleton.objectsList.Clear();
            singleton.barrelsList.Clear();

            // clear the singleton
            singleton = null;

            manteiga = null;
            keiJow = null;

            if (gameplayScreen != null)
            {
                gameplayScreen.ExitScreen();
            }
        }
    }

    public static void ChangeMap(int mapID)
    {
        singleton.solved = false;

        if (!singleton.firstTime)
        {
            bool actualSolved = true;

            foreach (Object obj in singleton.objectsList)
            {
                if (obj.GetType() == typeof(PuzzleObject))
                {
                    PuzzleObject puz = (PuzzleObject)obj;

                    if (puz.Kind == ObjectKind.WallUp && !puz.State)
                    {
                        actualSolved = false;
                        break;
                    }
                }
            }

            if (actualSolved)
                singleton.puzzleSolved.Add(singleton.actualMap);

            singleton.actualMap = mapID;

            foreach (int map in singleton.puzzleSolved)
            {
                if (map == singleton.actualMap)
                {
                    singleton.solved = true;
                }
            }
        }

        singleton.firstTime = false;

        //Console.WriteLine("blas " + singleton.firstTime + "  " + mapID + "  " + singleton.solved);

        singleton.charactersList = new List<Characters>();

        singleton.objectsList = new List<Objects>();

        //singleton.barrelsList = new List<Barrel>();

        singleton.puzzleManager.PuzzleGroups = new List<PuzzleGroup>();
        
        List<Characters> toDelete = new List<Characters>();

        /*foreach(Characters chara in singleton.characters)
        {
            if (chara.GetType() != typeof(KeiJow)
                && chara.GetType() != typeof(Manteiga))
            {
                toDelete.Add(chara);
            }
        }

        foreach(Characters chara in toDelete)
        {
            singleton.characters.Remove(chara);
        }*/
        
        
        if (keiJow != null && keiJow.State != Characters.States.Dead)
        {
            singleton.charactersList.Add(keiJow);
        }
        if (manteiga != null && manteiga.State != Characters.States.Dead)
        {
            singleton.charactersList.Add(manteiga);
        }

        for (int i = 0; i < singleton.barrelsList.Count; i++)
        {
            if (singleton.barrelsList[i].Rolled)
            {
                singleton.barrelsList.RemoveAt(i);
            }
        }

        singleton.mapcontroler.loadMap(mapID, out singleton.sceneryMatriz, out singleton.collisionMatriz, out singleton.objectsMatriz, out singleton.eventsMatriz);
        singleton.puzzleManager.CheckPuzzles(singleton.objectsMatriz, singleton.eventsMatriz, singleton.solved);
        singleton.eventManager.CheckEvents(singleton.objectsMatriz, singleton.eventsMatriz);
    }

    private bool inTouch = false;

    public static void HandleCollisions(Vector2 Position, Vector2 previousPosition, Rectangle previousBounding, Rectangle BoundingRectangle, out Vector2 finalPosition, bool isPlayer, Player player)
    {
        finalPosition = Position;

        if (BoundingRectangle.Y < 0 || BoundingRectangle.Y + BoundingRectangle.Height >= 720 || BoundingRectangle.X < 0 || BoundingRectangle.X  + BoundingRectangle.Width >= 1280)
            finalPosition = previousPosition;
        else
        if (GameSession.CollisionMatriz[(int)BoundingRectangle.X / 64, (int)(BoundingRectangle.Y) / 64] == 1 ||
            GameSession.CollisionMatriz[(int)BoundingRectangle.X / 64, (int)(BoundingRectangle.Y + BoundingRectangle.Height) / 64] == 1 ||
            GameSession.CollisionMatriz[(int)(BoundingRectangle.X + BoundingRectangle.Width) / 64, (int)(BoundingRectangle.Y) / 64] == 1 ||
            GameSession.CollisionMatriz[(int)(BoundingRectangle.X + BoundingRectangle.Width) / 64, (int)(BoundingRectangle.Y + BoundingRectangle.Height) / 64] == 1)
        {
            finalPosition = previousPosition;
        }

        if (isPlayer)
        {
            int posx = (int)(Position.X) / 64;
            int posy = (int)(Position.Y) / 64;
            int teleporter = GameSession.CollisionMatriz[posx, posy];

            if (teleporter == -99)
            {
                ScreenManager.AddScreen(new EndGame());

                Globals.IsPaused = true;
            }
            else
            if (teleporter < 0)
            {
                GameSession.ChangeMap(teleporter * -1);

                if (posx > 18)
                {
                    Position = new Vector2(2 * 64, ((int)(finalPosition.Y / 64)) * 64 + 30);

                    singleton.startPosition = Position;

                    if (keiJow != null) keiJow.Position = Position;
                    if (manteiga != null) manteiga.Position = Position;
                }
                else
                if (posx < 3)
                {
                    Position = new Vector2(18 * 64, ((int)(finalPosition.Y / 64)) * 64 + 30);

                    singleton.startPosition = Position;

                    if (keiJow != null) keiJow.Position = Position;
                    if (manteiga != null) manteiga.Position = Position;
                }
                else
                if (posy > 10)
                {
                    Position = new Vector2(((int)(finalPosition.X / 64)) * 64 + 30, 2 * 64);

                    singleton.startPosition = Position;

                    if (keiJow != null) keiJow.Position = Position;
                    if (manteiga != null) manteiga.Position = Position;
                }
                else
                if (posy < 3)
                {
                    Position = new Vector2(((int)(finalPosition.X / 64)) * 64 + 30, 10 * 64);

                    singleton.startPosition = Position;

                    if (keiJow != null) keiJow.Position = Position;
                    if (manteiga != null) manteiga.Position = Position;
                }

                return;

            }
        }
        int posxx = -1, posyy = -1;
        if (GameSession.CollisionMatriz[(int)BoundingRectangle.X / 64, (int)(BoundingRectangle.Y) / 64] == 2)
        {

            //Console.WriteLine("primeiro caso");
            posxx = (int)BoundingRectangle.X / 64;
            posyy = (int)(BoundingRectangle.Y) / 64;
            ObjectCollision(posxx, posyy, finalPosition, previousPosition, previousBounding, BoundingRectangle, out finalPosition, isPlayer, player);
        }
        if (GameSession.CollisionMatriz[(int)BoundingRectangle.X / 64, (int)(BoundingRectangle.Y + BoundingRectangle.Height) / 64] == 2)
        {
            posxx = (int)BoundingRectangle.X / 64;
            posyy = (int)(BoundingRectangle.Y + BoundingRectangle.Height) / 64;
            ObjectCollision(posxx, posyy, finalPosition, previousPosition, previousBounding, BoundingRectangle, out finalPosition, isPlayer, player);
        }
        if (GameSession.CollisionMatriz[(int)(BoundingRectangle.X + BoundingRectangle.Width) / 64, (int)(BoundingRectangle.Y) / 64] == 2)
        {
            Console.WriteLine("terceiro caso");

            posxx = (int)(BoundingRectangle.X + BoundingRectangle.Width) / 64;
            posyy = (int)(BoundingRectangle.Y) / 64;
            ObjectCollision(posxx, posyy, finalPosition, previousPosition, previousBounding, BoundingRectangle, out finalPosition, isPlayer, player);
        }
        if (GameSession.CollisionMatriz[(int)(BoundingRectangle.X + BoundingRectangle.Width) / 64, (int)(BoundingRectangle.Y + BoundingRectangle.Height) / 64] == 2)
        {
            //Console.WriteLine("quarto caso");

            posxx = (int)(BoundingRectangle.X + BoundingRectangle.Width) / 64;
            posyy = (int)(BoundingRectangle.Y + BoundingRectangle.Height) / 64;
            ObjectCollision(posxx, posyy, finalPosition, previousPosition, previousBounding, BoundingRectangle, out finalPosition, isPlayer, player);
        }

        //Console.WriteLine(" posxx " + posxx);

    }

    private static void ObjectCollision(int posxx, int posyy, Vector2 Position, Vector2 previousPosition, Rectangle previousBounding, Rectangle BoundingRectangle, out Vector2 finalPosition, bool isPlayer, Player player)
    {
        finalPosition = Position;

        foreach (Objects obj in singleton.objectsList)
        {

            //Console.WriteLine(obj.Kind);
            if (obj.XPosition == posxx && obj.YPosition == posyy)
            {
                if (obj.CanCollide)
                {
                    finalPosition = previousPosition;
                    if (obj.Kind == ObjectKind.PushingStone && isPlayer)
                    {
                        PuzzleObject puzzleObj = (PuzzleObject)obj;

                        if (puzzleObj.XPosition * 64 < previousBounding.X + previousBounding.Width
                            && (puzzleObj.XPosition * 64 + 64) > previousBounding.X
                            && puzzleObj.YPosition * 64 >= previousBounding.Y + previousBounding.Height)
                        {
                            puzzleObj.Direction = Direction.Down;
                            //Console.WriteLine("direçao: " + puzzleObj.Direction);
                        }
                        else
                            if (puzzleObj.XPosition * 64 < previousBounding.X + previousBounding.Width
                            && (puzzleObj.XPosition * 64 + 64) > previousBounding.X
                            && puzzleObj.YPosition * 64 + 64 <= previousBounding.Y)
                            {
                                puzzleObj.Direction = Direction.Up;
                                //Console.WriteLine("direçao: " + puzzleObj.Direction);
                            }
                            else
                                if (puzzleObj.YPosition * 64 < previousBounding.Y + previousBounding.Height
                                && (puzzleObj.YPosition * 64 + 64) > previousBounding.Y
                                && puzzleObj.XPosition * 64 + 64 <= previousBounding.X)
                                {
                                    puzzleObj.Direction = Direction.Left;
                                    //Console.WriteLine("direçao: " + puzzleObj.Direction);
                                }
                                else
                                    if (puzzleObj.YPosition * 64 < previousBounding.Y + previousBounding.Height
                                    && (puzzleObj.YPosition * 64 + 64) > previousBounding.Y
                                    && puzzleObj.XPosition * 64 >= previousBounding.X + previousBounding.Width)
                                    {
                                        puzzleObj.Direction = Direction.Right;
                                        //Console.WriteLine("direçao: " + puzzleObj.Direction);
                                    }
                        puzzleObj.State = true;
                    }
                    else
                    {
                        if (isPlayer && !player.HasBarrel && obj.Kind == ObjectKind.Barrel)
                        {
                            if (player.player == Player.PlayerNumber.ONE)
                            {
                                if (InputManager.IsActionPressed(InputManager.Action.Player1PickBarrel))
                                {
                                    _barrel = new Barrel(new Vector2(obj.XPosition * 64, obj.YPosition * 64));
                                    _barrel.LoadContent(Content);
                                    singleton.barrelsList.Add(_barrel);
                                    obj.Kind = ObjectKind.Useless;
                                    player._Barrel = _barrel;
                                    player.HasBarrel = true;
                                }
                            }
                            else
                            {
                                if (InputManager.IsActionPressed(InputManager.Action.Player2PickBarrel))
                                {
                                    _barrel = new Barrel(new Vector2(obj.XPosition * 64, obj.YPosition * 64));
                                    _barrel.LoadContent(Content);
                                    singleton.barrelsList.Add(_barrel);
                                    obj.Kind = ObjectKind.Useless;
                                    player._Barrel = _barrel;
                                    player.HasBarrel = true;
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (obj.Kind == ObjectKind.TrapDown)
                    {
                        Trap trap = (Trap)obj;
                        if (isPlayer)
                        {
                            if (trap.TrapKind == TrapKind.Timer && !trap.State)
                                trap.State = true;
                            else
                            {
                                if (trap.State)
                                {
                                    player.TakeDamage(1);
                                }
                            }
                        }
                        else
                        {
                            trap.State = false;
                        }
                    }
                }
            }

        }
    }

    public static Objects GetObject(int posx, int posy)
    {
        foreach(Objects obj in singleton.objectsList)
        {
            if(obj.XPosition == posx && obj.YPosition == posy)
                return obj;
        }

        return null;
    }

    public static void CheckPlayerPosition()
    {

        foreach (PuzzleObject obj in singleton.objectsList)
        {
            if (obj.Kind == ObjectKind.WallUp)
            {
                if (obj.State && !singleton.solved)
                    CheckPlayerPosition((int)obj.XPosition, (int)obj.YPosition);
            }
        }  

    }
}

